from rest_framework import viewsets, status
from rest_framework.decorators import action
from rest_framework.response import Response
from rest_framework.permissions import IsAuthenticated, AllowAny
from rest_framework.views import APIView
from django.utils import timezone
from django.db.models import Q
from django.contrib.auth.models import User
from django.utils.dateparse import parse_datetime
from django.views.decorators.csrf import csrf_exempt
from django.utils.decorators import method_decorator
import logging
import json

from .models import (
    GitLabServer, Project, Environment, UserProjectPermission,
    GitLabProject, GitLabUser, GitLabAudit, DevOpsTimeline
)
from .serializers import (
    GitLabServerSerializer, GitLabServerListSerializer, ProjectSerializer,
    EnvironmentSerializer, UserProjectPermissionSerializer, GitLabProjectSerializer,
    GitLabProjectUpdateSerializer, GitLabUserSerializer, GitLabAuditSerializer, DevOpsTimelineSerializer
)
from .gitlab_api import GitLabAPIManager

logger = logging.getLogger(__name__)


def create_devops_timeline_event(event_type, title, description, project=None, environment=None,
                                user=None, gitlab_project=None, status='success', details=None):
    """创建DevOps时间线事件的工具函数"""
    try:
        logger.info(f"🔄 开始创建DevOps时间线事件: {title}")
        logger.info(f"参数: event_type={event_type}, project={project}, environment={environment}, gitlab_project={gitlab_project}")

        # 如果没有提供项目和环境，尝试从gitlab_project获取
        if not project and gitlab_project and gitlab_project.project:
            project = gitlab_project.project
            logger.info(f"从GitLab项目获取项目: {project}")
        if not environment and gitlab_project and gitlab_project.environment:
            environment = gitlab_project.environment
            logger.info(f"从GitLab项目获取环境: {environment}")

        # 如果还是没有项目或环境，记录警告但仍然尝试创建（使用默认值）
        if not project or not environment:
            logger.warning(f"⚠️ DevOps时间线事件缺少项目或环境信息 - {title}")
            logger.warning(f"project: {project}, environment: {environment}, gitlab_project: {gitlab_project}")

            # 尝试获取默认的项目和环境
            if not project:
                try:
                    project = Project.objects.first()
                    logger.info(f"使用默认项目: {project}")
                except Exception as e:
                    logger.error(f"无法获取默认项目: {e}")
                    return None

            if not environment:
                try:
                    environment = Environment.objects.first()
                    logger.info(f"使用默认环境: {environment}")
                except Exception as e:
                    logger.error(f"无法获取默认环境: {e}")
                    return None

        logger.info(f"准备创建时间线事件: project={project}, environment={environment}, user={user}")

        timeline_event = DevOpsTimeline.objects.create(
            project=project,
            environment=environment,
            user=user,
            event_type=event_type,
            title=title,
            description=description,
            gitlab_project=gitlab_project,
            status=status,
            details=details or {}
        )
        logger.info(f"✅ 创建DevOps时间线事件成功: {timeline_event.id} - {title}")
        return timeline_event
    except Exception as e:
        logger.error(f"❌ 创建DevOps时间线事件失败: {e}")
        logger.error(f"详细参数: event_type={event_type}, project={project}, environment={environment}, user={user}")
        import traceback
        logger.error(f"错误堆栈: {traceback.format_exc()}")
        return None


class GitLabServerViewSet(viewsets.ModelViewSet):
    """GitLab服务器管理"""
    queryset = GitLabServer.objects.all()
    permission_classes = [IsAuthenticated]

    def get_serializer_class(self):
        if self.action == 'list':
            return GitLabServerListSerializer
        return GitLabServerSerializer

    @action(detail=True, methods=['post'])
    def test_connection(self, request, pk=None):
        """测试GitLab服务器连接"""
        server = self.get_object()

        try:
            # 更新状态为测试中
            server.status = 'testing'
            server.save()

            # 测试连接
            api_manager = GitLabAPIManager(server)
            result = api_manager.test_connection()

            if result['success']:
                server.status = 'connected'
                server.last_check = timezone.now()

                # 记录审计日志
                GitLabAudit.objects.create(
                    gitlab_server=server,
                    user=request.user,
                    operation_type='gitlab_server_test',
                    target_name=server.name,
                    description=f'测试GitLab服务器连接: {server.url}',
                    result='success',
                    details=result
                )
            else:
                server.status = 'error'

                # 记录审计日志
                GitLabAudit.objects.create(
                    gitlab_server=server,
                    user=request.user,
                    operation_type='gitlab_server_test',
                    target_name=server.name,
                    description=f'测试GitLab服务器连接: {server.url}',
                    result='failed',
                    error_message=result['message']
                )

            server.save()

            return Response({
                'success': result['success'],
                'message': result['message'],
                'status': server.status
            })

        except Exception as e:
            logger.error(f"测试GitLab连接失败: {e}")
            server.status = 'error'
            server.save()

            # 记录审计日志
            GitLabAudit.objects.create(
                gitlab_server=server,
                user=request.user,
                operation_type='gitlab_server_test',
                target_name=server.name,
                description=f'测试GitLab服务器连接: {server.url}',
                result='failed',
                error_message=str(e)
            )

            return Response({
                'success': False,
                'message': f'连接测试失败: {str(e)}',
                'status': server.status
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=False, methods=['post'])
    def test_all_connections(self, request):
        """测试所有GitLab服务器连接"""
        servers = self.get_queryset().filter(is_active=True)
        results = []

        for server in servers:
            try:
                api_manager = GitLabAPIManager(server)
                result = api_manager.test_connection()

                if result['success']:
                    server.status = 'connected'
                    server.last_check = timezone.now()
                else:
                    server.status = 'error'

                server.save()

                results.append({
                    'server_id': server.id,
                    'server_name': server.name,
                    'success': result['success'],
                    'message': result['message']
                })

            except Exception as e:
                server.status = 'error'
                server.save()

                results.append({
                    'server_id': server.id,
                    'server_name': server.name,
                    'success': False,
                    'message': str(e)
                })

        return Response({
            'success': True,
            'message': f'完成 {len(servers)} 个服务器的连接测试',
            'results': results
        })

    @action(detail=True, methods=['post'])
    def sync_projects(self, request, pk=None):
        """同步GitLab项目"""
        server = self.get_object()

        try:
            api_manager = GitLabAPIManager(server)
            result = api_manager.sync_projects()

            if result['success']:
                server.last_sync = timezone.now()
                server.save()

                # 记录审计日志
                GitLabAudit.objects.create(
                    gitlab_server=server,
                    user=request.user,
                    operation_type='gitlab_project_sync',
                    target_name=server.name,
                    description=f'同步GitLab项目: {result["count"]}个',
                    result='success',
                    details=result
                )

            return Response(result)

        except Exception as e:
            logger.error(f"同步GitLab项目失败: {e}")

            # 记录审计日志
            GitLabAudit.objects.create(
                gitlab_server=server,
                user=request.user,
                operation_type='gitlab_project_sync',
                target_name=server.name,
                description=f'同步GitLab项目失败',
                result='failed',
                error_message=str(e)
            )

            return Response({
                'success': False,
                'message': f'同步项目失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['get'])
    def branches(self, request, pk=None):
        """获取项目分支列表"""
        project = self.get_object()

        try:
            api_manager = GitLabAPIManager(project.gitlab_server)
            branches = api_manager.client.get_branches(project.gitlab_id)

            return Response({
                'success': True,
                'data': branches
            })

        except Exception as e:
            logger.error(f"获取项目 {project.name} 分支列表失败: {e}")
            return Response({
                'success': False,
                'message': f'获取分支列表失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['get'])
    def commits(self, request, pk=None):
        """获取项目提交记录"""
        project = self.get_object()
        branch = request.query_params.get('branch', 'main')

        try:
            api_manager = GitLabAPIManager(project.gitlab_server)
            commits = api_manager.client.get_commits(project.gitlab_id, branch)

            return Response({
                'success': True,
                'data': commits
            })

        except Exception as e:
            logger.error(f"获取项目 {project.name} 提交记录失败: {e}")
            return Response({
                'success': False,
                'message': f'获取提交记录失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'])
    def create_gitlab_project(self, request, pk=None):
        """在GitLab上创建新项目"""
        server = self.get_object()

        name = request.data.get('name')
        description = request.data.get('description', '')
        visibility = request.data.get('visibility', 'private')

        if not name:
            return Response({
                'success': False,
                'message': '项目名称不能为空'
            }, status=status.HTTP_400_BAD_REQUEST)

        try:
            api_manager = GitLabAPIManager(server)
            result = api_manager.create_gitlab_project(name, description, visibility)

            if result['success']:
                # 记录审计日志
                GitLabAudit.objects.create(
                    gitlab_server=server,
                    user=request.user,
                    operation_type='gitlab_project_create',
                    target_name=name,
                    description=f'在GitLab上创建项目: {name}',
                    result='success',
                    details=result
                )

            return Response(result)

        except Exception as e:
            logger.error(f"创建GitLab项目失败: {e}")

            # 记录审计日志
            GitLabAudit.objects.create(
                gitlab_server=server,
                user=request.user,
                operation_type='gitlab_project_create',
                target_name=name,
                description=f'创建GitLab项目失败',
                result='failed',
                error_message=str(e)
            )

            return Response({
                'success': False,
                'message': f'创建项目失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'])
    def configure_webhooks(self, request, pk=None):
        """自动配置GitLab项目的Webhooks"""
        server = self.get_object()

        try:
            api_manager = GitLabAPIManager(server)

            # 获取当前域名作为Webhook URL
            webhook_url = f"{request.build_absolute_uri('/')[:-1]}/api/gitlab/webhook/"

            # 获取服务器下的所有项目
            gitlab_projects = GitLabProject.objects.filter(gitlab_server=server)
            results = []

            for project in gitlab_projects:
                try:
                    # 为每个项目配置Webhook
                    result = api_manager.configure_project_webhook(
                        project.gitlab_id,
                        webhook_url
                    )

                    results.append({
                        'project_id': project.gitlab_id,
                        'project_name': project.name,
                        'success': result['success'],
                        'message': result['message']
                    })

                    # 记录审计日志
                    GitLabAudit.objects.create(
                        gitlab_server=server,
                        gitlab_project=project,
                        user=request.user,
                        operation_type='gitlab_webhook_config',
                        target_name=project.name,
                        description=f'配置项目Webhook: {webhook_url}',
                        result='success' if result['success'] else 'failed',
                        details=result,
                        error_message=result.get('message') if not result['success'] else None
                    )

                except Exception as e:
                    logger.error(f"配置项目 {project.name} Webhook失败: {e}")
                    results.append({
                        'project_id': project.gitlab_id,
                        'project_name': project.name,
                        'success': False,
                        'message': f'配置失败: {str(e)}'
                    })

            success_count = len([r for r in results if r['success']])
            total_count = len(results)

            return Response({
                'success': True,
                'message': f'配置完成：{success_count}/{total_count} 个项目成功',
                'results': results,
                'webhook_url': webhook_url
            })

        except Exception as e:
            logger.error(f"配置Webhooks失败: {e}")
            return Response({
                'success': False,
                'message': f'配置失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=False, methods=['post'])
    def sync_history_data(self, request):
        """同步GitLab历史数据"""
        try:
            total_synced = 0
            results = []

            # 获取所有GitLab服务器
            servers = GitLabServer.objects.filter(status='connected')
            logger.info(f"找到 {len(servers)} 个已连接的GitLab服务器")

            for server in servers:
                try:
                    logger.info(f"开始同步服务器: {server.name}")
                    api_manager = GitLabAPIManager(server)

                    # 获取服务器下的所有项目
                    projects = GitLabProject.objects.filter(gitlab_server=server)
                    logger.info(f"服务器 {server.name} 下有 {len(projects)} 个项目")

                    for project in projects:
                        try:
                            logger.info(f"开始同步项目: {project.name} (ID: {project.gitlab_id})")

                            # 获取项目信息以确定默认分支
                            project_info = api_manager.client.get_project(project.gitlab_id)
                            default_branch = project_info.get('default_branch', 'main')
                            logger.info(f"项目 {project.name} 默认分支: {default_branch}")

                            # 同步项目的提交历史
                            commits = api_manager.client.get_commits(project.gitlab_id, default_branch, per_page=50)
                            logger.info(f"项目 {project.name} 获取到 {len(commits)} 个提交记录")

                            for commit in commits:
                                # 检查是否已存在该提交的审计记录
                                existing = GitLabAudit.objects.filter(
                                    gitlab_project=project,
                                    operation_type='gitlab_commit',
                                    details__commit_id=commit.get('id')
                                ).exists()

                                logger.info(f"检查提交 {commit.get('short_id')} 是否存在: {existing}")

                                if not existing:
                                    # 解析GitLab时间格式
                                    commit_time = None
                                    try:
                                        from dateutil import parser
                                        commit_time = parser.parse(commit.get('created_at'))
                                    except:
                                        commit_time = timezone.now()

                                    # 创建提交审计记录
                                    GitLabAudit.objects.create(
                                        gitlab_server=server,
                                        gitlab_project=project,
                                        user=None,  # 历史数据可能没有对应的本地用户
                                        operation_type='gitlab_commit',
                                        target_name=commit.get('title', '')[:255],
                                        description=f"代码提交: {commit.get('message', '')}",
                                        result='success',
                                        details={
                                            'commit_id': commit.get('id'),
                                            'short_id': commit.get('short_id'),
                                            'author_name': commit.get('author_name'),
                                            'author_email': commit.get('author_email'),
                                            'message': commit.get('message'),
                                            'created_at': commit.get('created_at'),
                                            'web_url': commit.get('web_url'),
                                            'stats': commit.get('stats', {}),
                                            'parent_ids': commit.get('parent_ids', [])
                                        },
                                        created_at=commit_time
                                    )
                                    total_synced += 1
                                    logger.info(f"同步提交记录: {commit.get('short_id')} - {commit.get('title')}")

                            # 同步项目的标签历史
                            tags = api_manager.client.get_tags(project.gitlab_id)

                            for tag in tags[:10]:  # 只同步最新的10个标签
                                # 检查是否已存在该标签的审计记录
                                existing = GitLabAudit.objects.filter(
                                    gitlab_project=project,
                                    operation_type='gitlab_tag',
                                    details__tag_name=tag.get('name')
                                ).exists()

                                if not existing:
                                    # 创建标签审计记录
                                    GitLabAudit.objects.create(
                                        gitlab_server=server,
                                        gitlab_project=project,
                                        user=None,
                                        operation_type='gitlab_tag',
                                        target_name=tag.get('name', '')[:255],
                                        description=f"标签操作: {tag.get('name', '')}",
                                        result='success',
                                        details={
                                            'tag_name': tag.get('name'),
                                            'message': tag.get('message'),
                                            'target': tag.get('target'),
                                            'commit': tag.get('commit'),
                                            'release': tag.get('release')
                                        }
                                    )
                                    total_synced += 1

                            results.append({
                                'project_name': project.name,
                                'success': True,
                                'message': f'同步成功'
                            })

                        except Exception as e:
                            logger.error(f"同步项目 {project.name} 历史数据失败: {e}")
                            logger.error(f"异常详情: {type(e).__name__}: {str(e)}")
                            import traceback
                            logger.error(f"异常堆栈: {traceback.format_exc()}")
                            results.append({
                                'project_name': project.name,
                                'success': False,
                                'message': f'同步失败: {str(e)}'
                            })

                except Exception as e:
                    logger.error(f"同步服务器 {server.name} 历史数据失败: {e}")
                    results.append({
                        'server_name': server.name,
                        'success': False,
                        'message': f'服务器同步失败: {str(e)}'
                    })

            return Response({
                'success': True,
                'message': f'历史数据同步完成，共同步 {total_synced} 条记录',
                'total_synced': total_synced,
                'results': results
            })

        except Exception as e:
            logger.error(f"同步历史数据失败: {e}")
            return Response({
                'success': False,
                'message': f'同步失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=False, methods=['get'])
    def test_sync_aiops(self, request):
        """测试同步aiops项目"""
        try:
            # 直接获取aiops项目 (ID=2)
            project = GitLabProject.objects.get(id=2)
            server = project.gitlab_server

            logger.info(f"测试同步项目: {project.name}")

            api_manager = GitLabAPIManager(server)

            # 获取项目信息
            project_info = api_manager.client.get_project(project.gitlab_id)
            default_branch = project_info.get('default_branch', 'main')
            logger.info(f"项目默认分支: {default_branch}")

            # 获取提交记录
            commits = api_manager.client.get_commits(project.gitlab_id, default_branch, per_page=10)
            logger.info(f"获取到 {len(commits)} 个提交记录")

            synced_count = 0
            for commit in commits:
                logger.info(f"处理提交: {commit.get('short_id')} - {commit.get('title')}")

                # 检查是否已存在
                existing = GitLabAudit.objects.filter(
                    gitlab_project=project,
                    operation_type='gitlab_commit',
                    details__commit_id=commit.get('id')
                ).exists()

                logger.info(f"提交 {commit.get('short_id')} 是否已存在: {existing}")

                if not existing:
                    # 创建审计记录
                    from dateutil import parser
                    commit_time = parser.parse(commit.get('created_at'))

                    audit = GitLabAudit.objects.create(
                        gitlab_server=server,
                        gitlab_project=project,
                        user=None,
                        operation_type='gitlab_commit',
                        target_name=commit.get('title', '')[:255],
                        description=f"代码提交: {commit.get('message', '')}",
                        result='success',
                        details={
                            'commit_id': commit.get('id'),
                            'short_id': commit.get('short_id'),
                            'author_name': commit.get('author_name'),
                            'author_email': commit.get('author_email'),
                            'message': commit.get('message'),
                            'created_at': commit.get('created_at'),
                            'web_url': commit.get('web_url'),
                            'stats': commit.get('stats', {}),
                            'parent_ids': commit.get('parent_ids', [])
                        },
                        created_at=commit_time
                    )
                    synced_count += 1
                    logger.info(f"创建提交审计记录: {audit.id}")

            return Response({
                'success': True,
                'message': f'测试同步完成，同步了 {synced_count} 条记录',
                'synced_count': synced_count,
                'total_commits': len(commits)
            })

        except Exception as e:
            logger.error(f"测试同步失败: {e}")
            import traceback
            logger.error(f"异常堆栈: {traceback.format_exc()}")
            return Response({
                'success': False,
                'message': f'测试同步失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'])
    def sync_users(self, request, pk=None):
        """同步GitLab用户"""
        server = self.get_object()

        try:
            api_manager = GitLabAPIManager(server)
            result = api_manager.sync_users()

            if result['success']:
                server.last_sync = timezone.now()
                server.save()

                # 记录审计日志
                GitLabAudit.objects.create(
                    gitlab_server=server,
                    user=request.user,
                    operation_type='gitlab_user_sync',
                    target_name=server.name,
                    description=f'同步GitLab用户: {result["count"]}个',
                    result='success',
                    details=result
                )

            return Response(result)

        except Exception as e:
            logger.error(f"同步GitLab用户失败: {e}")

            # 记录审计日志
            GitLabAudit.objects.create(
                gitlab_server=server,
                user=request.user,
                operation_type='gitlab_user_sync',
                target_name=server.name,
                description=f'同步GitLab用户失败',
                result='failed',
                error_message=str(e)
            )

            return Response({
                'success': False,
                'message': f'同步用户失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'])
    def sync_local_users_to_gitlab(self, request, pk=None):
        """同步本地用户到GitLab"""
        server = self.get_object()

        try:
            api_manager = GitLabAPIManager(server)
            result = api_manager.sync_local_users_to_gitlab()

            if result['success']:
                server.last_sync = timezone.now()
                server.save()

                # 记录审计日志
                GitLabAudit.objects.create(
                    gitlab_server=server,
                    user=request.user,
                    operation_type='local_user_sync_to_gitlab',
                    target_name=server.name,
                    description=f'同步本地用户到GitLab: {result["count"]}个',
                    result='success',
                    details=result
                )

            return Response(result)

        except Exception as e:
            logger.error(f"同步本地用户到GitLab失败: {e}")

            # 记录审计日志
            GitLabAudit.objects.create(
                gitlab_server=server,
                user=request.user,
                operation_type='local_user_sync_to_gitlab',
                target_name=server.name,
                description=f'同步本地用户到GitLab失败',
                result='failed',
                error_message=str(e)
            )

            return Response({
                'success': False,
                'message': f'同步本地用户到GitLab失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['get'])
    def get_projects(self, request, pk=None):
        """获取GitLab项目列表"""
        server = self.get_object()

        try:
            api_manager = GitLabAPIManager(server)
            projects = api_manager.client.get_projects()

            return Response({
                'success': True,
                'results': projects
            })

        except Exception as e:
            logger.error(f"获取GitLab项目列表失败: {e}")
            return Response({
                'success': False,
                'message': f'获取项目列表失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['get'])
    def get_project_members(self, request, pk=None):
        """获取项目成员"""
        server = self.get_object()
        project_id = request.query_params.get('project_id')

        if not project_id:
            return Response({
                'success': False,
                'message': '缺少project_id参数'
            }, status=status.HTTP_400_BAD_REQUEST)

        try:
            api_manager = GitLabAPIManager(server)
            members = api_manager.client.get_project_members(project_id)

            return Response(members)

        except Exception as e:
            logger.error(f"获取项目成员失败: {e}")
            return Response({
                'success': False,
                'message': f'获取项目成员失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'])
    def add_project_member(self, request, pk=None):
        """添加项目成员"""
        server = self.get_object()
        project_id = request.data.get('project_id')
        user_id = request.data.get('user_id')
        access_level = request.data.get('access_level')

        if not all([project_id, user_id, access_level]):
            return Response({
                'success': False,
                'message': '缺少必要参数'
            }, status=status.HTTP_400_BAD_REQUEST)

        try:
            api_manager = GitLabAPIManager(server)
            result = api_manager.client.add_project_member(project_id, user_id, access_level)

            return Response({
                'success': True,
                'data': result
            })

        except Exception as e:
            logger.error(f"添加项目成员失败: {e}")
            return Response({
                'success': False,
                'message': f'添加项目成员失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'])
    def update_project_member(self, request, pk=None):
        """更新项目成员权限"""
        server = self.get_object()
        project_id = request.data.get('project_id')
        user_id = request.data.get('user_id')
        access_level = request.data.get('access_level')

        if not all([project_id, user_id, access_level]):
            return Response({
                'success': False,
                'message': '缺少必要参数'
            }, status=status.HTTP_400_BAD_REQUEST)

        try:
            api_manager = GitLabAPIManager(server)
            result = api_manager.client.update_project_member(project_id, user_id, access_level)

            return Response({
                'success': True,
                'data': result
            })

        except Exception as e:
            logger.error(f"更新项目成员权限失败: {e}")
            return Response({
                'success': False,
                'message': f'更新项目成员权限失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'])
    def remove_project_member(self, request, pk=None):
        """移除项目成员"""
        server = self.get_object()
        project_id = request.data.get('project_id')
        user_id = request.data.get('user_id')

        if not all([project_id, user_id]):
            return Response({
                'success': False,
                'message': '缺少必要参数'
            }, status=status.HTTP_400_BAD_REQUEST)

        try:
            api_manager = GitLabAPIManager(server)
            result = api_manager.client.remove_project_member(project_id, user_id)

            return Response({
                'success': True,
                'data': result
            })

        except Exception as e:
            logger.error(f"移除项目成员失败: {e}")
            return Response({
                'success': False,
                'message': f'移除项目成员失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['get'], url_path=r'projects/(?P<project_id>[^/.]+)/branches')
    def get_project_branches(self, request, pk=None, project_id=None):
        """获取项目分支"""
        server = self.get_object()

        try:
            api_manager = GitLabAPIManager(server)
            result = api_manager.get_project_branches(project_id)

            if result['success']:
                return Response(result['data'])
            else:
                return Response({
                    'error': result['message']
                }, status=status.HTTP_400_BAD_REQUEST)

        except Exception as e:
            logger.error(f"获取项目分支失败: {e}")
            return Response({
                'error': f'获取分支失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['get'], url_path=r'projects/(?P<project_id>[^/.]+)/tags')
    def get_project_tags(self, request, pk=None, project_id=None):
        """获取项目标签"""
        server = self.get_object()

        try:
            api_manager = GitLabAPIManager(server)
            result = api_manager.get_project_tags(project_id)

            if result['success']:
                return Response(result['data'])
            else:
                return Response({
                    'error': result['message']
                }, status=status.HTTP_400_BAD_REQUEST)

        except Exception as e:
            logger.error(f"获取项目标签失败: {e}")
            return Response({
                'error': f'获取标签失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class ProjectViewSet(viewsets.ModelViewSet):
    """项目管理"""
    queryset = Project.objects.all()
    serializer_class = ProjectSerializer
    permission_classes = [IsAuthenticated]


class EnvironmentViewSet(viewsets.ModelViewSet):
    """环境管理"""
    queryset = Environment.objects.all()
    serializer_class = EnvironmentSerializer
    permission_classes = [IsAuthenticated]


class UserProjectPermissionViewSet(viewsets.ModelViewSet):
    """用户项目权限管理"""
    queryset = UserProjectPermission.objects.all()
    serializer_class = UserProjectPermissionSerializer
    permission_classes = [IsAuthenticated]

    def get_queryset(self):
        queryset = super().get_queryset()

        # 如果不是超级管理员，只能看到自己的权限
        if not self.request.user.is_superuser:
            queryset = queryset.filter(user=self.request.user)

        # 支持过滤
        user_id = self.request.query_params.get('user_id')
        project_id = self.request.query_params.get('project_id')
        environment_id = self.request.query_params.get('environment_id')

        if user_id:
            queryset = queryset.filter(user_id=user_id)
        if project_id:
            queryset = queryset.filter(project_id=project_id)
        if environment_id:
            queryset = queryset.filter(environment_id=environment_id)

        return queryset


class GitLabProjectViewSet(viewsets.ModelViewSet):
    """GitLab项目管理"""
    queryset = GitLabProject.objects.all()
    serializer_class = GitLabProjectSerializer
    permission_classes = [IsAuthenticated]

    def get_serializer_class(self):
        if self.action in ['update', 'partial_update']:
            return GitLabProjectUpdateSerializer
        return GitLabProjectSerializer

    def update(self, request, *args, **kwargs):
        """更新GitLab项目，同时同步到GitLab服务器"""
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)

        # 检查是否更新了可见性
        old_visibility = instance.visibility
        new_visibility = serializer.validated_data.get('visibility', old_visibility)

        # 先更新本地数据库
        self.perform_update(serializer)

        # 如果可见性发生变化，同步到GitLab
        if new_visibility != old_visibility:
            try:
                api_manager = GitLabAPIManager(instance.gitlab_server)
                update_data = {'visibility': new_visibility}
                result = api_manager.client.update_project(instance.gitlab_id, update_data)
                logger.info(f"成功更新GitLab项目可见性: {instance.name} -> {new_visibility}")

                # 记录审计日志
                GitLabAudit.objects.create(
                    gitlab_server=instance.gitlab_server,
                    gitlab_project=instance,
                    user=request.user,
                    operation_type='gitlab_project_update',
                    target_name=instance.name,
                    description=f'更新项目可见性: {old_visibility} -> {new_visibility}',
                    result='success',
                    details={'old_visibility': old_visibility, 'new_visibility': new_visibility}
                )
            except Exception as e:
                logger.error(f"同步GitLab项目可见性失败: {e}")
                # 记录审计日志
                GitLabAudit.objects.create(
                    gitlab_server=instance.gitlab_server,
                    gitlab_project=instance,
                    user=request.user,
                    operation_type='gitlab_project_update',
                    target_name=instance.name,
                    description=f'同步GitLab项目可见性失败',
                    result='failed',
                    error_message=str(e)
                )

        if getattr(instance, '_prefetched_objects_cache', None):
            instance._prefetched_objects_cache = {}

        return Response(serializer.data)

    def get_queryset(self):
        queryset = super().get_queryset()

        # 如果不是超级管理员，只能看到有权限的项目
        if not self.request.user.is_superuser:
            # 获取用户有权限的项目和环境
            user_permissions = UserProjectPermission.objects.filter(
                user=self.request.user,
                can_view=True
            ).values_list('project_id', 'environment_id')

            project_env_pairs = list(user_permissions)
            if project_env_pairs:
                q_objects = Q()
                for project_id, env_id in project_env_pairs:
                    q_objects |= Q(project_id=project_id, environment_id=env_id)
                queryset = queryset.filter(q_objects)
            else:
                queryset = queryset.none()

        # 支持过滤
        gitlab_server_id = self.request.query_params.get('gitlab_server_id')
        project_id = self.request.query_params.get('project_id')
        environment_id = self.request.query_params.get('environment_id')

        if gitlab_server_id:
            queryset = queryset.filter(gitlab_server_id=gitlab_server_id)
        if project_id:
            queryset = queryset.filter(project_id=project_id)
        if environment_id:
            queryset = queryset.filter(environment_id=environment_id)

        return queryset

    def _parse_datetime(self, datetime_str):
        """解析GitLab API返回的日期时间字符串"""
        if not datetime_str:
            return None
        try:
            return parse_datetime(datetime_str)
        except (ValueError, TypeError):
            return None

    @action(detail=False, methods=['post'])
    def sync_from_gitlab(self, request):
        """从GitLab同步项目"""
        gitlab_server_id = request.data.get('gitlab_server_id')

        if not gitlab_server_id:
            return Response({
                'success': False,
                'message': '缺少gitlab_server_id参数'
            }, status=status.HTTP_400_BAD_REQUEST)

        try:
            gitlab_server = GitLabServer.objects.get(id=gitlab_server_id)
            api_manager = GitLabAPIManager(gitlab_server)

            # 获取GitLab项目
            projects = api_manager.client.get_projects()
            logger.info(f"从GitLab获取到 {len(projects)} 个项目")

            synced_count = 0
            for project_data in projects:
                # 根据项目名称自动映射到本地项目和环境
                # 默认映射到第一个项目和开发环境
                try:
                    default_project = Project.objects.first()
                    default_environment = Environment.objects.filter(code='dev').first()

                    if not default_project or not default_environment:
                        continue

                    # 检查是否已存在
                    try:
                        gitlab_project = GitLabProject.objects.get(
                            gitlab_server=gitlab_server,
                            gitlab_id=project_data['id']
                        )
                        # 已存在，只更新GitLab相关字段，保留用户配置的项目和环境
                        gitlab_project.name = project_data['name']
                        gitlab_project.path = project_data['path']
                        gitlab_project.path_with_namespace = project_data['path_with_namespace']
                        gitlab_project.description = project_data.get('description', '')
                        gitlab_project.web_url = project_data['web_url']
                        gitlab_project.ssh_url_to_repo = project_data['ssh_url_to_repo']
                        gitlab_project.http_url_to_repo = project_data['http_url_to_repo']
                        gitlab_project.visibility = project_data['visibility']
                        gitlab_project.default_branch = project_data.get('default_branch')
                        gitlab_project.star_count = project_data.get('star_count', 0)
                        gitlab_project.forks_count = project_data.get('forks_count', 0)
                        gitlab_project.last_activity_at = self._parse_datetime(project_data.get('last_activity_at'))
                        gitlab_project.save()
                        created = False
                    except GitLabProject.DoesNotExist:
                        # 不存在，创建新记录（不设置默认项目和环境）
                        gitlab_project = GitLabProject.objects.create(
                            gitlab_server=gitlab_server,
                            gitlab_id=project_data['id'],
                            project=None,  # 新项目不设置默认项目
                            environment=None,  # 新项目不设置默认环境
                            name=project_data['name'],
                            path=project_data['path'],
                            path_with_namespace=project_data['path_with_namespace'],
                            description=project_data.get('description', ''),
                            web_url=project_data['web_url'],
                            ssh_url_to_repo=project_data['ssh_url_to_repo'],
                            http_url_to_repo=project_data['http_url_to_repo'],
                            visibility=project_data['visibility'],
                            default_branch=project_data.get('default_branch'),
                            star_count=project_data.get('star_count', 0),
                            forks_count=project_data.get('forks_count', 0),
                            last_activity_at=self._parse_datetime(project_data.get('last_activity_at')),
                        )
                        created = True
                    synced_count += 1
                    logger.info(f"成功同步项目: {project_data['name']}")
                except Exception as e:
                    logger.error(f"同步项目 {project_data.get('name', 'unknown')} 失败: {e}")
                    import traceback
                    logger.error(traceback.format_exc())
                    continue

            # 更新服务器统计信息
            gitlab_server.project_count = len(projects)
            gitlab_server.last_sync = timezone.now()
            gitlab_server.save()

            return Response({
                'success': True,
                'message': f'成功同步 {synced_count} 个项目',
                'count': synced_count
            })

        except GitLabServer.DoesNotExist:
            return Response({
                'success': False,
                'message': 'GitLab服务器不存在'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"同步GitLab项目失败: {e}")
            return Response({
                'success': False,
                'message': f'同步失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['get'])
    def branches(self, request, pk=None):
        """获取项目分支列表"""
        project = self.get_object()

        try:
            api_manager = GitLabAPIManager(project.gitlab_server)
            branches = api_manager.client.get_branches(project.gitlab_id)

            return Response({
                'success': True,
                'data': branches
            })

        except Exception as e:
            logger.error(f"获取项目 {project.name} 分支列表失败: {e}")
            return Response({
                'success': False,
                'message': f'获取分支列表失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['get'])
    def commits(self, request, pk=None):
        """获取项目提交记录"""
        project = self.get_object()
        branch = request.query_params.get('branch', 'main')

        try:
            api_manager = GitLabAPIManager(project.gitlab_server)
            commits = api_manager.client.get_commits(project.gitlab_id, branch)

            return Response({
                'success': True,
                'data': commits
            })

        except Exception as e:
            logger.error(f"获取项目 {project.name} 提交记录失败: {e}")
            return Response({
                'success': False,
                'message': f'获取提交记录失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)


class GitLabUserViewSet(viewsets.ModelViewSet):
    """GitLab用户管理"""
    queryset = GitLabUser.objects.all()
    serializer_class = GitLabUserSerializer
    permission_classes = [IsAuthenticated]

    def get_queryset(self):
        queryset = super().get_queryset()

        # 支持过滤
        gitlab_server_id = self.request.query_params.get('gitlab_server_id')
        mapping_filter = self.request.query_params.get('mapping_filter')

        if gitlab_server_id:
            queryset = queryset.filter(gitlab_server_id=gitlab_server_id)

        if mapping_filter == 'mapped':
            queryset = queryset.filter(local_user__isnull=False)
        elif mapping_filter == 'unmapped':
            queryset = queryset.filter(local_user__isnull=True)

        return queryset

    @action(detail=False, methods=['post'])
    def sync_from_gitlab(self, request):
        """从GitLab同步用户"""
        gitlab_server_id = request.data.get('gitlab_server_id')

        if not gitlab_server_id:
            return Response({
                'success': False,
                'message': '缺少gitlab_server_id参数'
            }, status=status.HTTP_400_BAD_REQUEST)

        try:
            gitlab_server = GitLabServer.objects.get(id=gitlab_server_id)
            api_manager = GitLabAPIManager(gitlab_server)

            # 获取GitLab用户
            users = api_manager.client.get_users()

            synced_count = 0
            for user_data in users:
                gitlab_user, created = GitLabUser.objects.update_or_create(
                    gitlab_server=gitlab_server,
                    gitlab_id=user_data['id'],
                    defaults={
                        'username': user_data['username'],
                        'name': user_data['name'],
                        'email': user_data['email'],
                        'state': user_data.get('state', 'active'),
                        'is_admin': user_data.get('is_admin', False),
                        'avatar_url': user_data.get('avatar_url'),
                        'web_url': user_data.get('web_url'),
                    }
                )
                synced_count += 1

            # 更新服务器统计信息
            gitlab_server.user_count = len(users)
            gitlab_server.last_sync = timezone.now()
            gitlab_server.save()

            return Response({
                'success': True,
                'message': f'成功同步 {synced_count} 个用户',
                'count': synced_count
            })

        except GitLabServer.DoesNotExist:
            return Response({
                'success': False,
                'message': 'GitLab服务器不存在'
            }, status=status.HTTP_404_NOT_FOUND)
        except Exception as e:
            logger.error(f"同步GitLab用户失败: {e}")
            return Response({
                'success': False,
                'message': f'同步失败: {str(e)}'
            }, status=status.HTTP_500_INTERNAL_SERVER_ERROR)

    @action(detail=True, methods=['post'])
    def map_to_local_user(self, request, pk=None):
        """映射到本地用户"""
        gitlab_user = self.get_object()

        # 检查是否包含local_user_id参数
        if 'local_user_id' not in request.data:
            return Response({
                'success': False,
                'message': '缺少local_user_id参数'
            }, status=status.HTTP_400_BAD_REQUEST)

        local_user_id = request.data.get('local_user_id')

        # 如果local_user_id为None或空字符串，则取消映射
        if local_user_id is None or local_user_id == '' or local_user_id == 'null':
            gitlab_user.local_user = None
            gitlab_user.save()
            return Response({
                'success': True,
                'message': f'成功取消用户 {gitlab_user.username} 的映射'
            })

        # 检查local_user_id是否为有效值
        if not local_user_id:
            return Response({
                'success': False,
                'message': 'local_user_id参数无效'
            }, status=status.HTTP_400_BAD_REQUEST)

        try:
            local_user = User.objects.get(id=local_user_id)
            gitlab_user.local_user = local_user
            gitlab_user.save()

            return Response({
                'success': True,
                'message': f'成功映射用户 {gitlab_user.username} 到 {local_user.username}'
            })

        except User.DoesNotExist:
            return Response({
                'success': False,
                'message': '本地用户不存在'
            }, status=status.HTTP_404_NOT_FOUND)

    @action(detail=True, methods=['post'])
    def unmap_user(self, request, pk=None):
        """取消用户映射"""
        gitlab_user = self.get_object()
        gitlab_user.local_user = None
        gitlab_user.save()

        return Response({
            'success': True,
            'message': f'成功取消用户 {gitlab_user.username} 的映射'
        })


class GitLabAuditViewSet(viewsets.ReadOnlyModelViewSet):
    """GitLab操作审计"""
    queryset = GitLabAudit.objects.all()
    serializer_class = GitLabAuditSerializer
    permission_classes = [IsAuthenticated]

    def get_queryset(self):
        queryset = super().get_queryset()

        # 支持过滤
        gitlab_server_id = self.request.query_params.get('gitlab_server_id')
        gitlab_project = self.request.query_params.get('gitlab_project')
        operation_type = self.request.query_params.get('operation_type')
        result = self.request.query_params.get('result')
        user_id = self.request.query_params.get('user_id')
        search = self.request.query_params.get('search')

        # 日期范围过滤
        created_at__gte = self.request.query_params.get('created_at__gte')
        created_at__lte = self.request.query_params.get('created_at__lte')

        if gitlab_server_id:
            queryset = queryset.filter(gitlab_server_id=gitlab_server_id)
        if gitlab_project:
            queryset = queryset.filter(gitlab_project_id=gitlab_project)
        if operation_type:
            queryset = queryset.filter(operation_type=operation_type)
        if result:
            queryset = queryset.filter(result=result)
        if user_id:
            queryset = queryset.filter(user_id=user_id)
        if created_at__gte:
            queryset = queryset.filter(created_at__gte=created_at__gte)
        if created_at__lte:
            queryset = queryset.filter(created_at__lte=created_at__lte)

        # 搜索功能
        if search:
            queryset = queryset.filter(
                Q(target_name__icontains=search) |
                Q(description__icontains=search) |
                Q(user__username__icontains=search) |
                Q(user__first_name__icontains=search) |
                Q(user__last_name__icontains=search)
            )

        return queryset


class DevOpsTimelineViewSet(viewsets.ReadOnlyModelViewSet):
    """DevOps操作时间线"""
    queryset = DevOpsTimeline.objects.all()
    serializer_class = DevOpsTimelineSerializer
    permission_classes = [IsAuthenticated]

    def get_queryset(self):
        queryset = super().get_queryset()

        # 如果不是超级管理员，只能看到有权限的项目
        if not self.request.user.is_superuser:
            # 获取用户有权限的项目和环境
            user_permissions = UserProjectPermission.objects.filter(
                user=self.request.user,
                can_view=True
            ).values_list('project_id', 'environment_id')

            project_env_pairs = list(user_permissions)
            if project_env_pairs:
                q_objects = Q()
                for project_id, env_id in project_env_pairs:
                    q_objects |= Q(project_id=project_id, environment_id=env_id)
                queryset = queryset.filter(q_objects)
            else:
                queryset = queryset.none()

        # 支持过滤
        project_id = self.request.query_params.get('project_id')
        environment_id = self.request.query_params.get('environment_id')
        event_type = self.request.query_params.get('event_type')
        user_id = self.request.query_params.get('user_id')

        if project_id:
            queryset = queryset.filter(project_id=project_id)
        if environment_id:
            queryset = queryset.filter(environment_id=environment_id)
        if event_type:
            queryset = queryset.filter(event_type=event_type)
        if user_id:
            queryset = queryset.filter(user_id=user_id)

        return queryset


@method_decorator(csrf_exempt, name='dispatch')
class GitLabWebhookView(APIView):
    """GitLab Webhook接收器"""
    permission_classes = [AllowAny]

    def post(self, request):
        """处理GitLab Webhook事件"""
        try:
            # 获取事件类型
            event_type = request.headers.get('X-Gitlab-Event')
            if not event_type:
                return Response({'error': 'Missing X-Gitlab-Event header'}, status=400)

            # 解析请求数据
            webhook_data = request.data

            # 根据事件类型处理
            if event_type == 'Push Hook':
                self._handle_push_event(webhook_data)
            elif event_type == 'Merge Request Hook':
                self._handle_merge_request_event(webhook_data)
            elif event_type == 'Tag Push Hook':
                self._handle_tag_event(webhook_data)
            elif event_type == 'Pipeline Hook':
                self._handle_pipeline_event(webhook_data)

            return Response({'status': 'success'})

        except Exception as e:
            logger.error(f"处理GitLab Webhook失败: {e}")
            return Response({'error': str(e)}, status=500)

    def _handle_push_event(self, data):
        """处理推送事件"""
        try:
            project_data = data.get('project', {})
            user_data = data.get('user_name', 'Unknown')
            commits = data.get('commits', [])

            logger.info(f"处理推送事件: 项目={project_data.get('name')}, 用户={user_data}, 提交数量={len(commits)}")

            # 查找对应的GitLab项目
            gitlab_project = None
            try:
                gitlab_project = GitLabProject.objects.get(gitlab_id=project_data.get('id'))
                logger.info(f"找到对应的GitLab项目: {gitlab_project.name}")
            except GitLabProject.DoesNotExist:
                logger.warning(f"未找到GitLab项目: {project_data.get('id')}")

            # 查找对应的用户 - 先尝试通过GitLab用户映射查找
            user = None
            try:
                # 首先尝试通过GitLab用户映射查找
                if gitlab_project and gitlab_project.gitlab_server:
                    gitlab_user = GitLabUser.objects.filter(
                        gitlab_server=gitlab_project.gitlab_server,
                        username=user_data
                    ).first()

                    if gitlab_user and gitlab_user.local_user:
                        user = gitlab_user.local_user
                        logger.info(f"通过GitLab用户映射找到用户: {user.username}")
                    else:
                        # 如果没有映射，尝试直接通过用户名查找
                        user = User.objects.filter(username=user_data).first()
                        if user:
                            logger.info(f"直接通过用户名找到用户: {user.username}")
                        else:
                            logger.warning(f"未找到用户: {user_data}")
                else:
                    # 如果没有项目信息，直接通过用户名查找
                    user = User.objects.filter(username=user_data).first()
                    if user:
                        logger.info(f"直接通过用户名找到用户: {user.username}")
                    else:
                        logger.warning(f"未找到用户: {user_data}")
            except Exception as e:
                logger.warning(f"查找用户失败: {e}")

            # 为每个提交创建审计记录
            for commit in commits:
                # 获取提交作者信息
                author_info = commit.get('author', {})

                audit = GitLabAudit.objects.create(
                    gitlab_server=gitlab_project.gitlab_server if gitlab_project else None,
                    gitlab_project=gitlab_project,
                    user=user,
                    operation_type='gitlab_commit',
                    target_name=commit.get('message', '').split('\n')[0][:255],  # 取第一行作为标题
                    description=f"代码提交: {commit.get('message', '')}",
                    result='success',
                    details={
                        'commit_id': commit.get('id'),
                        'commit_url': commit.get('url'),
                        'branch': data.get('ref', '').replace('refs/heads/', ''),
                        'author_name': author_info.get('name'),
                        'author_email': author_info.get('email'),
                        'committer_name': commit.get('committer', {}).get('name'),
                        'committer_email': commit.get('committer', {}).get('email'),
                        'gitlab_user': user_data,  # 保存GitLab用户名
                        'added_files': commit.get('added', []),
                        'modified_files': commit.get('modified', []),
                        'removed_files': commit.get('removed', [])
                    }
                )
                logger.info(f"创建提交审计记录: {audit.id} - {commit.get('id')}")

                # 创建DevOps时间线事件
                create_devops_timeline_event(
                    event_type='gitlab_commit',
                    title=commit.get('message', '').split('\n')[0][:255],
                    description=f"代码提交到 {data.get('ref', '').replace('refs/heads/', '')} 分支",
                    gitlab_project=gitlab_project,
                    user=user,
                    status='success',
                    details={
                        'commit_id': commit.get('id'),
                        'commit_url': commit.get('url'),
                        'branch': data.get('ref', '').replace('refs/heads/', ''),
                        'author_name': author_info.get('name'),
                        'author_email': author_info.get('email'),
                        'files_changed': len(commit.get('added', [])) + len(commit.get('modified', [])) + len(commit.get('removed', []))
                    }
                )

        except Exception as e:
            logger.error(f"处理推送事件失败: {e}")

    def _handle_merge_request_event(self, data):
        """处理合并请求事件"""
        try:
            project_data = data.get('project', {})
            user_data = data.get('user', {})
            mr_data = data.get('object_attributes', {})

            # 查找对应的GitLab项目
            gitlab_project = None
            try:
                gitlab_project = GitLabProject.objects.get(gitlab_id=project_data.get('id'))
            except GitLabProject.DoesNotExist:
                pass

            # 查找对应的用户
            user = None
            try:
                user = User.objects.get(username=user_data.get('username'))
            except User.DoesNotExist:
                pass

            # 创建审计记录
            GitLabAudit.objects.create(
                gitlab_server=gitlab_project.gitlab_server if gitlab_project else None,
                gitlab_project=gitlab_project,
                user=user,
                operation_type='gitlab_merge',
                target_name=mr_data.get('title', '')[:255],
                description=f"合并请求: {mr_data.get('action', '')} - {mr_data.get('title', '')}",
                result='success',
                details={
                    'merge_request_id': mr_data.get('id'),
                    'merge_request_iid': mr_data.get('iid'),
                    'action': mr_data.get('action'),
                    'source_branch': mr_data.get('source_branch'),
                    'target_branch': mr_data.get('target_branch'),
                    'state': mr_data.get('state'),
                    'url': mr_data.get('url')
                }
            )

        except Exception as e:
            logger.error(f"处理合并请求事件失败: {e}")

    def _handle_tag_event(self, data):
        """处理标签事件"""
        try:
            project_data = data.get('project', {})
            user_data = data.get('user_name', 'Unknown')
            ref = data.get('ref', '')

            logger.info(f"处理标签事件: 项目={project_data.get('name')}, 用户={user_data}, 标签={ref}")

            # 查找对应的GitLab项目
            gitlab_project = None
            try:
                gitlab_project = GitLabProject.objects.get(gitlab_id=project_data.get('id'))
                logger.info(f"找到对应的GitLab项目: {gitlab_project.name}")
            except GitLabProject.DoesNotExist:
                logger.warning(f"未找到GitLab项目: {project_data.get('id')}")

            # 查找对应的用户 - 先尝试通过GitLab用户映射查找
            user = None
            try:
                # 首先尝试通过GitLab用户映射查找
                if gitlab_project and gitlab_project.gitlab_server:
                    gitlab_user = GitLabUser.objects.filter(
                        gitlab_server=gitlab_project.gitlab_server,
                        username=user_data
                    ).first()

                    if gitlab_user and gitlab_user.local_user:
                        user = gitlab_user.local_user
                        logger.info(f"通过GitLab用户映射找到用户: {user.username}")
                    else:
                        # 如果没有映射，尝试直接通过用户名查找
                        user = User.objects.filter(username=user_data).first()
                        if user:
                            logger.info(f"直接通过用户名找到用户: {user.username}")
                        else:
                            logger.warning(f"未找到用户: {user_data}")
                else:
                    # 如果没有项目信息，直接通过用户名查找
                    user = User.objects.filter(username=user_data).first()
                    if user:
                        logger.info(f"直接通过用户名找到用户: {user.username}")
                    else:
                        logger.warning(f"未找到用户: {user_data}")
            except Exception as e:
                logger.warning(f"查找用户失败: {e}")

            tag_name = ref.replace('refs/tags/', '')

            # 创建审计记录，包含GitLab用户信息
            audit = GitLabAudit.objects.create(
                gitlab_server=gitlab_project.gitlab_server if gitlab_project else None,
                gitlab_project=gitlab_project,
                user=user,
                operation_type='gitlab_tag',
                target_name=tag_name,
                description=f"标签操作: {tag_name}",
                result='success',
                details={
                    'tag_name': tag_name,
                    'ref': ref,
                    'checkout_sha': data.get('checkout_sha'),
                    'commits': data.get('commits', []),
                    'gitlab_user': user_data,  # 保存GitLab用户名
                    'user_email': data.get('user_email'),  # 保存用户邮箱
                    'user_avatar': data.get('user_avatar')  # 保存用户头像
                }
            )
            logger.info(f"创建标签审计记录: {audit.id} - {tag_name}")

        except Exception as e:
            logger.error(f"处理标签事件失败: {e}")

    def _handle_pipeline_event(self, data):
        """处理流水线事件"""
        try:
            project_data = data.get('project', {})
            user_data = data.get('user', {})
            pipeline_data = data.get('object_attributes', {})

            # 查找对应的GitLab项目
            gitlab_project = None
            try:
                gitlab_project = GitLabProject.objects.get(gitlab_id=project_data.get('id'))
            except GitLabProject.DoesNotExist:
                pass

            # 查找对应的用户
            user = None
            try:
                user = User.objects.get(username=user_data.get('username'))
            except User.DoesNotExist:
                pass

            # 创建审计记录
            GitLabAudit.objects.create(
                gitlab_server=gitlab_project.gitlab_server if gitlab_project else None,
                gitlab_project=gitlab_project,
                user=user,
                operation_type='gitlab_pipeline',
                target_name=f"Pipeline #{pipeline_data.get('id')}",
                description=f"流水线: {pipeline_data.get('status')} - {pipeline_data.get('ref')}",
                result='success' if pipeline_data.get('status') == 'success' else 'failed',
                details={
                    'pipeline_id': pipeline_data.get('id'),
                    'status': pipeline_data.get('status'),
                    'ref': pipeline_data.get('ref'),
                    'sha': pipeline_data.get('sha'),
                    'duration': pipeline_data.get('duration'),
                    'url': pipeline_data.get('url')
                }
            )

        except Exception as e:
            logger.error(f"处理流水线事件失败: {e}")
